<?php
// +----------------------------------------------------------------------
// | Options服务服务层
// +----------------------------------------------------------------------
// | 主要服务于Options数据处理
// +----------------------------------------------------------------------
// | 错误编码头 214xxx
// +----------------------------------------------------------------------
namespace common\service;

use common\exception\LogicException;
use common\model\DirectoryTemplateModel;
use common\model\ProjectModel;
use common\model\ProjectTemplateModel;
use support\ErrorCode;
use think\Exception;

class DirectoryTemplateService
{
    /**
     * 获取指定模板内容
     * @param $id
     * @return array|mixed
     * @throws \Exception
     */
    public function getTemplateData($id)
    {
        $directoryTemplateModel = model(DirectoryTemplateModel::class);
        $options = [
            'fields' => "template_content",
            'filter' => ['id' => $id]
        ];
        $resData = $directoryTemplateModel->findData($options);
        return array_key_exists("template_content", $resData) ? $resData['template_content'] : [];
    }

    /**
     * 删除
     * @param $filter
     * @return array
     * @throws \Exception
     */
    public function delete($filter)
    {
        // 获取当前模块删除主键
        $directoryTemplateModel = model(DirectoryTemplateModel::class);
        $masterIdData = $directoryTemplateModel->field('id')->where($filter)->select();

        if (!empty($masterIdData)) {
            $masterIds = join(',', array_column($masterIdData, 'id'));
            try {
                $resData = $directoryTemplateModel->deleteItem([
                    'id' => ["IN", $masterIds]
                ]);

                $projectTemplateList = model(ProjectTemplateModel::class)->where(['directory_template_id' => ["IN", $masterIds]])->select();
                if (!empty($projectTemplateList)) {
                    model(ProjectTemplateModel::class)->where(['directory_template_id' => ["IN", $masterIds]])->save(['directory_template_id' => 0]);
                }
            } catch (LogicException $e) {
                throw new LogicException("template not exist", ErrorCode::TEMPLATE_NOT_EXIST);
            }

            if (!$resData) {
                throw new LogicException("template not exist", ErrorCode::TEMPLATE_NOT_EXIST);
            } else {
                // 返回成功数据
                return ['ids' => $masterIds];
            }
        } else {
            throw new LogicException('Delete item does not exist.', ErrorCode::DELETE_ITEM_NOT_EXIST);
        }
    }

    /**
     * 获取指定Options设置项值
     * @param $projectTemplateId
     * @param $itemName
     * @return array|mixed
     * @throws \Exception
     */
    public function getTemplateContentTypeData($id, $itemName = [])
    {
        //默认不取内部的类型
        $configData = $this->getTemplateData($id);
        return $this->dealTemplate($configData, $itemName);
    }

    public function dealTemplate($configData, $itemName = [])
    {

        $itemNames = ["work", "review", "publish"];
        if (is_array($itemName)) {
            if (empty($configData)) {
                return [];
            }

            $result = [];
            foreach ($configData as $type => $item) {
                if (empty($itemName) || in_array($type, $itemName)) {
                    if (in_array($type, $itemNames)) {
                        $result["$type"] = $configData["$type"];
                    } else {
                        $result = array_merge($result, $item);
                    }
                }
            }
            return $result;
        } else {
            if (empty($configData) || !array_key_exists($itemName, $configData)) {
                return '';
            }

            if (in_array($itemName, $itemNames)) {
                return ["$itemName" => $configData["$itemName"]];
            }
            return $configData["$itemName"];
        }
    }

    /**
     * 通用添加配置
     * @param $params
     * @param string $message
     * @return array|bool
     * @throws \Exception
     */
    public function addTemplateData($params, $message = '')
    {
        $directoryTemplateModel = model(DirectoryTemplateModel::class);
        $findOptionsResult = $directoryTemplateModel->findData(["filter" => ["name" => $params['name']]]);

        if (!empty($findOptionsResult)) {
            $updateData = [
                'id' => $findOptionsResult['id'],
                'name' => $params['name'],
                'template_content' => $params['template_content']
            ];
            return $directoryTemplateModel->modifyItem($updateData);
        } else {
            $addData = [
                'name' => $params['name'],
                'template_content' => $params['template_content']
            ];
            return $directoryTemplateModel->addItem($addData);
        }
    }

    /**
     * 通过项目id获取模板内容
     * @param $projectId
     * @param $itemName
     * @return array|mixed|string
     * @throws \Exception
     */
    public function getTemplateContentItemDataByProject($filter, $itemName = [])
    {
        $field = [
            "work_dir_prefix","engine_dir_prefix","directory_template",
            "JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$.','version_file_work'))) as version_file_work",
            "JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$.','version_file_review'))) as version_file_review",
            "JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$.','version_file_public'))) as version_file_publish",
            "JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$.','local_dir_prefix'))) as local_dir_prefix",
            "JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$.','center_storage'))) as center_storage",
            "JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$.','is_new_storage'))) as is_new_storage",
        ];

        $project = model(ProjectModel::class)
            ->where($filter)
            ->field($field)
            ->find();

        $workDirPrefix = $project["work_dir_prefix"] ?? "";
        $engineDirPrefix = $project["engine_dir_prefix"] ?? "";
        $directoryTemplate = [];
        if (!empty($project["directory_template"])) {
            $directoryTemplate = json_decode($project["directory_template"], true);
        }

        $tmp = [
            "work_dir"             => $workDirPrefix, "review_dir" => $workDirPrefix, "publish_dir" => $workDirPrefix,
            "migrate_dir"          => $workDirPrefix, "cache_dir" => $workDirPrefix, "render_dir" => $workDirPrefix,
            "engine_dir"           => $engineDirPrefix, "version_file_work" => $project["version_file_work"] ?? "",
            "version_file_review"  => $project["version_file_review"] ?? "",
            "version_file_publish" => $project["version_file_publish"] ?? "",
            "local_dir_prefix"     => $project["local_dir_prefix"] ?? "",
            "is_new_storage"     => $project["is_new_storage"] ?? "",
            "center_storage"       => json_decode($project['center_storage'], true) ?? "",
        ];

        $directoryTemplate = $this->dealTemplate($directoryTemplate, $itemName);
        return array_merge($tmp, $directoryTemplate);
    }

    /**
     * 获取默认的目录模板
     * @return array|mixed
     * @throws \Exception
     */
    public function getOptionsTemplate()
    {

        $defDirTemplate = OptionsService::getInstance()->getOptionsData("def_dir_template");
        if (empty($defDirTemplate)) {
            throw new LogicException("options not exist dir template", ErrorCode::OPTIONS_NOT_EXIST_DIR_TEMPLATE);
        }
        return $defDirTemplate;
    }

    /**
     * 保存类型
     * @param $id
     * @param $type
     * @param array $data
     * @return array|bool
     * @throws \Exception
     */
    public function saveType($id, $type, $data = [])
    {
        $templateData = $this->getTemplateData($id);
        $templateData[$type] = $data;
        return model(DirectoryTemplateModel::class)->modifyItem(['id' => $id, 'template_content' => $templateData]);
    }

    /**
     * 删除类型
     * @param $id
     * @param $type
     * @return array|bool
     * @throws \Exception
     */
    public function deleteType($id, $type)
    {
        $templateData = $this->getTemplateData($id);
        unset($templateData[$type]);
        return model(DirectoryTemplateModel::class)->modifyItem(['id' => $id, 'template_content' => $templateData]);
    }

    /**
     * 保存子项
     * @param $id
     * @param $type
     * @param $data
     * @return bool|int|string
     * @throws \Exception
     */
    public function saveItem($id, $type, $data)
    {
        $templateData = $this->getTemplateData($id);
        if (!empty($templateData)) {
            if (!array_key_exists($type, $templateData)) {
                throw new LogicException("dir template not exist type", ErrorCode::DIR_TEMPLATE_NOT_EXIST_TYPE);
            }
            $templateData[$type][$data['dir_name']] = $data['dir_path'];
        }

        return model(DirectoryTemplateModel::class)->modifyItem(['id' => $id, 'template_content' => $templateData]);
    }

    /**
     * 删除类型下的子项
     * @param $id
     * @param $type
     * @param $name
     * @return bool|int|string
     * @throws \Exception
     */
    public function deleteItem($id, $type, $name)
    {
        $templateData = $this->getTemplateData($id);
        if (!empty($templateData)) {
            if (!array_key_exists($type, $templateData)) {
                throw new LogicException("dir template not exist type", ErrorCode::DIR_TEMPLATE_NOT_EXIST_TYPE);
            }
            unset($templateData[$type][$name]);
        }

        return model(DirectoryTemplateModel::class)->modifyItem(['id' => $id, 'template_content' => $templateData]);
    }
}
